#include <iostream>

class Test
{
public:
    Test(){std::cout<<"构造函数！\n";}
    ~Test(){std::cout<<"析构函数！\n";}
    void show()
    {
        std::cout<<"hello world"<<std::endl;
    }

};

// 智能指针
// 在构造里维护指针，在析构里自动释放
class SmartPoint
{
public:
    SmartPoint(Test *t):t(t){}
    ~SmartPoint()
    {
        delete t;
    }

    Test *get()
    {
        return t;
    }

    // 重载 ->（可以像指针一样去使用某一个类型的对象）
    Test *operator->()
    {
        return t;
    }

    // 重载 *
    Test &operator*() // 左值返回都是引用，减少拷贝，右值返回都是变量，因为右值会发生RVO优化，不会发生拷贝
    {
        return *t;
    }
private:
    Test *t;

};

int main()
{
    // 定义这样一个智能指针去维护一个test对象
    SmartPoint p(new Test); // 把在堆上申请的一个Test的指针交给智能指针p去维护和管理，在构造时把p给它，在析构时自动把它释放，像p这个对象，就能自动帮助我们去管理Test对象，防止内存泄漏，很好用
    // p.get()->show(); // 这样有点不好，相当于我原来的目的是把你指针管理起来，帮你自动释放，结果现在想调用你指针下的函数，还得把你指针拿出来再调用，这样就违背了初心，这是有点危险的，所以想能不能直接p->show()这样用，这样就避免把维护起来的指针拿出来用了，更安全，所以要重载->
    Test *t;
    p->show();
    // 获取指针指向的对象
    (*p).show(); // 同理，想把指针里的东西拿到就得以*p这样的形式，就得重载*
    return 0;
}